import random
import string
from openpyxl import Workbook
from collections import deque


def generate_wechat_nickname():
    """生成符合微信规则的随机昵称"""
    # 配置参数
    MAX_LENGTH = 20  # 微信昵称最大字符数
    EMOJI_PROB = 0.3  # 包含表情符号的概率
    NUM_PROB = 0.4  # 包含数字的概率

    # 基础组件
    components = {
        'chinese': [
            '星辰', '清风', '阳光', '飞鸟', '蓝天', '白云', '大海', '青山', '绿树', '花开',
            '时光', '岁月', '流年', '静好', '安然', '初心', '远方', '诗意', '浅笑', '暖阳',
            '雨露', '彩虹', '梦想', '希望', '勇气', '自由', '和平', '快乐', '幸福', '安康',
            '悠然', '静谧', '温馨', '浪漫', '热情', '温柔', '聪慧', '优雅', '真诚', '善良'
        ],
        'english': [
            'Sun', 'Moon', 'Star', 'Sky', 'Ocean', 'River', 'Mountain', 'Flower',
            'Rainbow', 'Dream', 'Hope', 'Peace', 'Joy', 'Happy', 'Love', 'Smile',
            'Angel', 'Butterfly', 'Freedom', 'Summer', 'Winter', 'Spring', 'Autumn',
            'Coffee', 'Tea', 'Book', 'Music', 'Art', 'Travel', 'Nature'
        ],
        'digits': [str(i) for i in range(1900, 2024)] + [str(i).zfill(2) for i in range(1, 100)],
        'emojis': [
            '😊', '🌟', '🌙', '🌈', '🌸', '🎵', '🎨', '📚', '☕', '🌊',
            '⛰️', '⚡', '💖', '🎈', '🎉', '✨', '🌍', '🍀', '🦋', '🐬'
        ],
        'special_chars': ['·', '-', '_', '|', '~']
    }

    # 生成组件队列用于保证多样性
    component_queue = deque(maxlen=10)

    def get_component(category):
        """获取不同组件并保证最近10次不重复"""
        pool = components[category]
        for _ in range(50):  # 最多尝试50次
            item = random.choice(pool)
            if item not in component_queue:
                component_queue.append(item)
                return item
        return random.choice(pool)  # 保底返回随机项

    # 构建昵称
    parts = []
    current_length = 0

    # 随机选择基础类型
    base_type = random.choices(
        population=['chinese', 'english', 'mixed'],
        weights=[0.5, 0.3, 0.2],
        k=1
    )[0]

    # 添加基础部分
    if base_type == 'chinese':
        part = get_component('chinese')
        parts.append(part)
        current_length += len(part)
        if random.random() < 0.6 and current_length < MAX_LENGTH - 2:
            parts.append(get_component('chinese'))
            current_length += len(parts[-1])
    elif base_type == 'english':
        part = get_component('english')
        parts.append(part)
        current_length += len(part)
    else:  # mixed
        parts.append(random.choice([
            get_component('chinese') + get_component('english'),
            get_component('english') + get_component('chinese')
        ]))
        current_length = len(parts[-1])

    # 添加数字
    if random.random() < NUM_PROB and current_length < MAX_LENGTH - 2:
        num = random.choice(components['digits'])
        if current_length + len(num) <= MAX_LENGTH:
            parts.append(num)
            current_length += len(num)

    # 添加分隔符
    if len(parts) > 1 and random.random() < 0.3:
        sep = random.choice(components['special_chars'])
        if current_length + 1 <= MAX_LENGTH:
            parts.insert(random.randint(0, len(parts)), sep)
            current_length += 1

    # 添加表情符号（最多2个）
    if random.random() < EMOJI_PROB:
        emoji_count = random.randint(1, 2)
        for _ in range(emoji_count):
            if current_length + 1 <= MAX_LENGTH:
                emoji = get_component('emojis')
                parts.append(emoji)
                current_length += 1

    # 随机排列组合并修剪长度
    random.shuffle(parts)
    nickname = ''.join(parts)[:MAX_LENGTH]

    return nickname


def generate_unique_nicknames(count=20000):
    """高效生成唯一昵称集合"""
    generated = set()
    retry_count = 0
    total_generated = 0

    while len(generated) < count:
        # 批量生成减少检查次数
        batch_size = min(1000, count - len(generated))
        batch = [generate_wechat_nickname() for _ in range(batch_size)]

        # 过滤重复
        unique_batch = list(set(batch) - generated)

        if not unique_batch:  # 如果整个批次都是重复的
            retry_count += 1
            if retry_count > 10:
                # 降低重复概率策略
                components['chinese'] += [c * 2 for c in components['chinese']]
                components['english'] += [e.lower() for e in components['english']]
                retry_count = 0
            continue

        generated.update(unique_batch)
        total_generated += len(unique_batch)

        # 进度显示
        if total_generated % 1000 == 0:
            print(f'已生成 {total_generated}/{count} ({total_generated / count:.1%})')

    return list(generated)[:count]


def save_to_excel(nicknames, filename="wechat_nicknames.xlsx"):
    """保存到Excel文件"""
    wb = Workbook()
    ws = wb.active
    ws.title = "微信昵称"
    ws.append(["微信昵称"])

    # 分批写入防止内存不足
    batch_size = 1000
    for i in range(0, len(nicknames), batch_size):
        batch = nicknames[i:i + batch_size]
        for name in batch:
            ws.append([name])
        print(f'已写入 {min(i + batch_size, len(nicknames))} 条记录')

    wb.save(filename)
    print(f"文件已保存为 {filename}")


if __name__ == "__main__":
    try:
        print("开始生成微信昵称...")
        nicknames = generate_unique_nicknames(20000)
        print("\n开始保存到Excel文件...")
        save_to_excel(nicknames)
        print("\n操作完成！")
    except Exception as e:
        print(f"发生错误：{str(e)}")